﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CTPAdapter;
using System.Threading;

namespace CTPDemo.Md
{
    class MdSpi:CSMdSpiInter,MdApiInter
    {
        /// <summary>
        /// 经纪公司代码
        /// </summary>
        string _BrokerID;

        /// <summary>
        /// 投资者代码
        /// </summary>
        string _InvestorID;

        /// <summary>
        /// 用户密码
        /// </summary>
        string _Password;

        /// <summary>
        /// 行情订阅列表
        /// </summary>
        string[] _ppInstrumentID;

        /// <summary>
        /// 行情订阅数量
        /// </summary>
        int _iInstrumentID;

        /// <summary>
        /// 行情API接口
        /// </summary>
        CSMdApi _MdApi;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="investorID"></param>
        /// <param name="password"></param>
        /// <param name="mdApi"></param>
        public MdSpi(string investorID, string password, CSMdApi mdApi, string[] ppInstrumentID, int iInstrumentID)
        {
            _BrokerID = "2030";
            _InvestorID = investorID;
            _Password = password;
            _MdApi = mdApi;
            _ppInstrumentID = ppInstrumentID;
            _iInstrumentID = iInstrumentID;
    
        }

        /// <summary>
        /// 是否收到成功的响应
        /// </summary>
        /// <param name="pRspInfo"></param>
        /// <returns></returns>
        private bool IsErrorRspInfo(CSCThostFtdcRspInfoField pRspInfo)
        {
            // 如果ErrorID != 0, 说明收到了错误的响应
            bool bResult = ((pRspInfo != null) && (pRspInfo.ErrorID != 0));
            if (bResult)
            //cerr << "--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << endl;
            {
                MdTest.MdTest1.DisplayError("ErrorID=" + pRspInfo.ErrorID + "    ErrorMsg=" + pRspInfo.ErrorMsg);
            }
            return bResult;
        }

        /// <summary>
        /// 用户登录请求
        /// <summary>
        public void ReqUserLogin()
        {
            CSCThostFtdcReqUserLoginField req = new CSCThostFtdcReqUserLoginField(); ;
            req.BrokerID = _BrokerID;
            req.UserID = _InvestorID;
            req.Password = _Password;

            _MdApi.ReqUserLogin(req);
        }

        /// <summary>
        /// 行情订阅请求
        /// <summary>     
        public void SubscribeMarketData()
        {
            
            int iResult = _MdApi.SubscribeMarketData(_ppInstrumentID, _iInstrumentID);

	        //cerr << "--->>> 发送行情订阅请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
        }

        /// <summary>
        /// 退订行情
        /// <summary>     
        public void UnSubscribeMarketData()
        {

            int iResult = _MdApi.UnSubscribeMarketData(_ppInstrumentID, _iInstrumentID);

            //cerr << "--->>> 发送行情订阅请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
        }

        /// <summary>
        /// 登出请求
        /// <summary>
        public void ReqUserLogout()
        {
            _MdApi.RegisterSpi(null);
            
            CSCThostFtdcUserLogoutField req = new CSCThostFtdcUserLogoutField();
            req.BrokerID = _BrokerID;
            req.UserID = _InvestorID;

            int iResult = _MdApi.ReqUserLogout(req);

        }

        public void Release()
        {
            _MdApi.Release();

        }


        /// <summary>
        /// 删除接口对象本身
        /// <summary>
        ///@remark 不再使用本接口对象时,调用该函数删除接口对象
        //public void Release()
        //{
        //    _MdApi.Release();
        //    //cerr << "--->>> 发送行情订阅请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
        //}

		/// <summary>
		///当客户端与交易后台建立起通信连接时（还未登录前），该方法被调用。
		/// <summary>
        public void OnFrontConnected()
        {
            ReqUserLogin();
        }

		/// <summary>
		///当客户端与交易后台通信连接断开时，该方法被调用。当发生这个情况后，API会自动重新连接，客户端可不做处理。
		///@param nReason 错误原因
		///        0x1001 网络读失败
		///        0x1002 网络写失败
		///        0x2001 接收心跳超时
		///        0x2002 发送心跳失败
		///        0x2003 收到错误报文
		/// <summary>
        public void OnFrontDisconnected(int nReason)
        {

        }

		/// <summary>
		///心跳超时警告。当长时间未收到报文时，该方法被调用。
		///@param nTimeLapse 距离上次接收报文的时间
		/// <summary>
        public void OnHeartBeatWarning(int nTimeLapse)
        {

        }


		/// <summary>
        /// 登录请求响应
        /// <summary>
        public void OnRspUserLogin(CSCThostFtdcRspUserLoginField pRspUserLogin, CSCThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {

            MdTest.MdTest1.DisplayError("登录请求响应-OnRspUserLogin");
            Thread.Sleep(1000);
            //cerr << "--->>> " << __FUNCTION__ << endl;
            if (bIsLast && !IsErrorRspInfo(pRspInfo))
            {
                ///获取当前交易日
                //cerr << "--->>> 获取当前交易日 = " << pUserApi->GetTradingDay() << endl;
                // 请求订阅行情
                SubscribeMarketData();
            }


        }

		/// <summary>
		/// 登出请求响应
		/// <summary>
        public void OnRspUserLogout(CSCThostFtdcUserLogoutField pUserLogout, CSCThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            
          
            MdTest.MdTest1.DisplayError("登出请求响应-OnRspUserLogout");
            Thread.Sleep(1000);
            
            //cerr << "--->>> " << __FUNCTION__ << endl;
            if (bIsLast && !IsErrorRspInfo(pRspInfo))
            {
                ///获取当前交易日
                //cerr << "--->>> 获取当前交易日 = " << pUserApi->GetTradingDay() << endl;
                // 删除接口对象本身
                //Release ();
            }

        }

		/// <summary>
		/// 错误应答
		/// <summary>
        public void OnRspError(CSCThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {

            MdTest.MdTest1.DisplayError("错误应答-OnRspError");

            
            //cerr << "--->>> " << __FUNCTION__ << endl;
            if (bIsLast && !IsErrorRspInfo(pRspInfo))
            {
            }

        }

		/// <summary>
		/// 订阅行情应答
		/// <summary>
        public void OnRspSubMarketData(CSCThostFtdcSpecificInstrumentField pSpecificInstrument, CSCThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            MdTest.MdTest1.DisplayError("OnRspSubMarketData==>" + pSpecificInstrument.InstrumentID );

        }

		/// <summary>
		/// 取消订阅行情应答
		/// <summary>
        public void OnRspUnSubMarketData(CSCThostFtdcSpecificInstrumentField pSpecificInstrument, CSCThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            MdTest.MdTest1.DisplayError("取消订阅行情应答-OnRspUnSubMarketData");
            //Thread.Sleep(1000);

            if (bIsLast && !IsErrorRspInfo(pRspInfo))
            {
                ///获取当前交易日
                //cerr << "--->>> 获取当前交易日 = " << pUserApi->GetTradingDay() << endl;
                // 登出请求
                ReqUserLogout();
            }
            

        }

		/// <summary>
		/// 深度行情通知
		/// <summary>
        public void OnRtnDepthMarketData(CSCThostFtdcDepthMarketDataField pDepthMarketData)
        {

            MdTest.MdTest1.DisplayError("OnRtnDepthMarketData==>" + pDepthMarketData.InstrumentID + ":" + pDepthMarketData.LastPrice);

        }




    }
}
